// initialize 
VIEW_FROM_QQ_APP = $("#qq_open_id").val();
DEBUG=0;
THUMB_WIDTH = VIEW_FROM_QQ_APP ? 60 : 60;
THUMB_HEIGHT = VIEW_FROM_QQ_APP ? 60 : 60;
BODY_WIDTH_FROM_QQ = 740;
THUMB_MARGIN_X = 10;
THUMB_MARGIN_Y = 10;
MAX_HORIZON_CHILD_NUM = 13;
X_LARGE_NUM = 28;
X_MEDIUM_NUM = 18;
NAME_HEIGHT = 15;
NAME_MARGIN_TOP=15;
MEMBER_COUNT=60;
QIN_TREE_MIN_WIDTH = VIEW_FROM_QQ_APP ? 690 : 300;
ASIDE_MIN_WIDTH = 300;
ASIDE_MAX_WIDTH = 960;
TREE_PADDING = 10;
RELATIVE_LINE_HEIGHT = 50;
BUTTON_WIDTH = 30;
BUTTON_HEIGHT = 15;
BUTTON_MARGIN_X = 5;
BUTTON_MARGIN_Y = 4;
BUTTON_FONT_HEIGHT = 10;
BUTTON_FONT_PADDING_LEFT = 3;
BUTTON_FONT_PADDING_TOP = 2;
BUTTON_FONT_STYLE = BUTTON_FONT_HEIGHT+"px 宋体";
MEMBER_BLOCK_HEIGHT = THUMB_HEIGHT + NAME_HEIGHT + THUMB_MARGIN_Y + NAME_MARGIN_TOP;
RADIUS = 5;
PARENT_RADIUS = 5;
CHILD_RADIUS = 2;
CHILD_POINT_PADDING = 7;
LEVEL = 3;
MAX_MATES = 2;
NAME_STYLE = "normal lighter 12px serif";
NAME_LENGTH = 3;
BASE_LINE = "top";
LINE_STYLE = '#B3614D';
THUMB_OUT_BORDER = "#999999";
ROOT_LINE_WIDTH = 4;
THUMB_BORDER_WIDTH = 2;
MALE_FIGURE = "/Public/Img/male.png";
FEMALE_FIGURE= "/Public/Img/female.png";
COLUMN = 9;
prev_x = 0;
prev_y = 0;

elements = [];
buttons = [];
names = [];
family = new Array();
canvas_margin_left = 0;
canvas_margin_top = 0;

canvas = '';//document.getElementById("canvas");
cxt = '';//canvas.getContext("2d");
canvas_top = '';//document.getElementById("canvas_top");
cxt_top = '';//canvas_top.getContext("2d");
authorized = 0;//$("#authorized").val();
line_width = new Array("0","1","1","1");
QIN_TREE_WIDTH = QIN_TREE_MIN_WIDTH;//canvas.clientWidth;
QIN_TREE_HEIGHT = 400;//(MEMBER_BLOCK_HEIGHT+RELATIVE_LINE_HEIGHT) * LEVEL - RELATIVE_LINE_HEIGHT + 10;
//QIN_TREE_HEIGHT = 1;//QIN_TREE_WIDTH;
// log("QIN_TREE_WIDTH: "+QIN_TREE_WIDTH);
child_num_level_1 =0;
child_num_level_2 =0;
child_num_level_3 =0;
horizon_child_num =0;
child_num_in_level = new Array(0,0,0,0);

function circle(canvas, x, y, r, color)
{
    canvas.fillStyle = color; 
    canvas.beginPath();
    canvas.arc(x, y, r, 0, 2 * Math.PI, true);
    canvas.closePath();
    canvas.fill();
}

function roundRectanglePath(context,x,y,w,h,radius)
{
    context.beginPath();
    context.moveTo( x+radius,y );
    context.lineTo( x+w-radius,y );
    context.arc( x+w-radius,y+radius, radius, 3*Math.PI/2,2*Math.PI, false);
    context.lineTo( x+w,y+h-radius);
    context.arc( x+w-radius,y+h-radius, radius, 0, Math.PI/2, false);
    context.lineTo( x+radius,y+h );
    context.arc( x+radius,y+h-radius, radius, Math.PI/2, Math.PI, false);
    context.lineTo( x,y+radius);
    context.arc( x+radius,y+radius, radius,Math.PI, 3*Math.PI/2, false);
    context.closePath();
}
function log(str)
{
    $("#msg1").html(str+"<br/>");
}
function pageX(elem) {//获取元素相对于整个文档的X位置的函数；
    var p = 0;
    while ( elem.offsetParent ) {
        p += elem.offsetLeft;
        elem = elem.offsetParent;
    }
    return p;
}
function pageY(elem){ //获取元素相对于整个文档的Y位置的函数；
    var p = 0;
    while ( elem.offsetParent ) {
        p += elem.offsetTop;
        elem = elem.offsetParent;
    }
    return p;
}
function getItem(array, e)
{
    // log("getItem");
    var mouse_x = e.pageX - canvas_margin_left;
    var mouse_y = e.pageY - canvas_margin_top;
    // search which member is hovered
    // log("will for");
    var find = false;
    // log("find = false");
    for(var i=0; i<array.length; i++)
    {
	// log("type: "+array[i].x1);
	if (mouse_x >= array[i].x1 && mouse_x <= array[i].x2 &&
	    mouse_y >= array[i].y1 && mouse_y <= array[i].y2)
	{
	    find = true;
	    break;
	}
    }
    // log("break");
    if (!find)
    {
	// log("return null");
	return null;
    }

    var a= array[i];
    return a;
}

function getRightestItem(array, e)
{
    // log("getItem");
    var mouse_x = e.pageX - canvas_margin_left;
    var mouse_y = e.pageY - canvas_margin_top;
    // search which member is hovered
    // log("will for");
    var find = 0;
    var right = mouse_x;
    
    // log("find = false");
    for(var i=0; i<array.length; i++)
    {
	// log("type: "+array[i].x1);
	if (mouse_y == array[i].y1 && right <= array[i].x2)
	{
	    find = i;
	    right = array[i].x2;
	}
    }
    // log("break");
    if (!find)
    {
	// log("return null");
	return null;
    }

    return array[find];
}
// draw buttons when you click on a person in a family tree,
// this function will draw 'add'/edit/del/show-main-page buttons on the right of the person
// 
//  +------+
//  |  __  | +----+
//  | /  \ | |edit|
//  | \__/ | +----+
//  |      |
//  +------+
function drawButtons(member)
{
    // log("member x1: "+member.x1)
    var x = member.x2 + BUTTON_MARGIN_X;
    var y = member.y1;
    // log("drawAddButton, x: "+x+"; y: "+y);

    var canvas_top = document.getElementById("canvas_top");
    var cxt_top = canvas_top.getContext("2d");
    cxt_top.fillStyle="white";
    cxt_top.strokeStyle="blue";
    cxt_top.font = BUTTON_FONT_STYLE; 

    cxt_top.fillRect(x, y, BUTTON_WIDTH, BUTTON_HEIGHT);
    cxt_top.strokeRect(x, y, BUTTON_WIDTH, BUTTON_HEIGHT);
    cxt_top.strokeText("主页", x+BUTTON_FONT_PADDING_LEFT, y+BUTTON_FONT_HEIGHT+BUTTON_FONT_PADDING_TOP);

    if (authorized)
    {
	cxt_top.fillRect(x, y+BUTTON_HEIGHT+BUTTON_MARGIN_Y, BUTTON_WIDTH, BUTTON_HEIGHT);
	cxt_top.strokeRect(x, y+BUTTON_HEIGHT+BUTTON_MARGIN_Y, BUTTON_WIDTH, BUTTON_HEIGHT);
	cxt_top.strokeText("添加", x+BUTTON_FONT_PADDING_LEFT, y+BUTTON_FONT_HEIGHT+BUTTON_FONT_PADDING_TOP
			   +BUTTON_HEIGHT+BUTTON_MARGIN_Y );
	// cxt_top.stroke();

	cxt_top.fillRect(x, y+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)*2, BUTTON_WIDTH, BUTTON_HEIGHT);
	cxt_top.strokeRect(x, y+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)*2, BUTTON_WIDTH, BUTTON_HEIGHT);
	cxt_top.strokeText("编辑", x+BUTTON_FONT_PADDING_LEFT, y+BUTTON_FONT_HEIGHT+BUTTON_FONT_PADDING_TOP+
			   (BUTTON_HEIGHT+BUTTON_MARGIN_Y)*2 );
	// cxt_top.stroke();

	cxt_top.fillRect(x, y+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)*3, BUTTON_WIDTH, BUTTON_HEIGHT);
	cxt_top.strokeRect(x, y+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)*3, BUTTON_WIDTH, BUTTON_HEIGHT);
	cxt_top.strokeText("删除", x+BUTTON_FONT_PADDING_LEFT, y+BUTTON_FONT_HEIGHT+BUTTON_FONT_PADDING_TOP+
			   (BUTTON_HEIGHT+BUTTON_MARGIN_Y)*3);
    }
    cxt_top.stroke();
    // log("add x1: "+x+", y1: "+y+", x2: "+(x + BUTTON_WIDTH)+", y2: "+(y+BUTTON_HEIGHT));
    buttons = [];
    buttons.push({type:"home", id:member.id, name:member.name, gender:member.gender, 
		  x1: x, y1: y, x2: x + BUTTON_WIDTH, y2:y+BUTTON_HEIGHT});
    if(authorized)
    {
	buttons.push({type:"add", id:member.id, name:member.name, gender:member.gender, 
    		      x1: x, y1: y+BUTTON_HEIGHT+BUTTON_MARGIN_Y, 
		      x2: x + BUTTON_WIDTH, y2:y+BUTTON_HEIGHT+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)});
	buttons.push({type:"edit", id:member.id, name:member.name, gender:member.gender, 
    		      x1: x, y1: y+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)*2, 
		      x2: x + BUTTON_WIDTH, y2:y+BUTTON_HEIGHT+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)*2});
	buttons.push({type:"del", id:member.id, name:member.name, gender:member.gender, 
    		      x1: x, y1: y+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)*3, 
		      x2: x + BUTTON_WIDTH, y2:y+BUTTON_HEIGHT+(BUTTON_HEIGHT+BUTTON_MARGIN_Y)*3});
    }
}
function selectMember(member, color)
{
    // log(" page x: "+e.pageX+"; page y: "+e.pageY);
    // var member = getItem(e);
    var x = member.x1;
    var y = member.y1;

    // in the same block, do nothing
    if (prev_x == x && prev_y == y)
	return;

    var w = member.x2 - member.x1;
    var h = member.y2 - member.y1;

    // move to another block, update the new block position
    prev_x = x;
    prev_y = y;

    // clear the mast layer and stroke the new border
    clearCanvas("canvas_top");
    cxt_top.strokeStyle = color;
    cxt_top.lineWidth = 3;
    // cxt_top.strokeRect(x, y, w, h);
    roundRectanglePath(cxt_top, x-2, y-2, w+4, h+4, RADIUS);
    cxt_top.stroke();
}

function clearCanvas(id)
{
    var canvas = document.getElementById(id);
    canvas.width = canvas.width;
    canvas.height = canvas.height;
}
$(document).ready(function(){
    $("#canvas_top").click(function(e){
	var a = new Object();
	a.pageX = e.pageX + parseInt($("#family-tree")[0].scrollLeft);
	a.pageY = e.pageY;
	
	var name = getItem(names, a);
	if (name)
	{
	    selectMember(name, "blue");
	    window.location = "/users/home?userid="+name.id;
	    return;
	}
	var member = getItem(elements, a);
	if (member)
	{
	    selectMember(member, "blue");
	    window.location.href = "/tree/index?userid="+member.id;
	}
    });
    $("#canvas_top").dblclick(function(e){
    });
    var canvas = $("#canvas_top")[0];	
    canvas.addEventListener('mousemove', onMouseMove, false); 
});
function onMouseMove(e){
    var a = new Object();
    a.pageX = e.pageX + parseInt($("#family-tree")[0].scrollLeft);
    a.pageY = e.pageY;
    if (obj = getItem(elements, a))
	selectMember(obj, "#3b9314");
    else if (obj = getItem(names, a))
	selectMember(obj, "#3b9314");    
}

// draw a member on a canvas
function drawMember(context, url, name, x, y)
{
    var img = new Image();
    img.onload = function(){context.drawImage(img, x, y, THUMB_WIDTH, THUMB_HEIGHT);
			    roundRectanglePath(context, x-1, y-1, THUMB_WIDTH+2, THUMB_HEIGHT+2, RADIUS);
			    context.strokeStyle = "white";
			    context.lineWidth = THUMB_BORDER_WIDTH;
			    context.stroke();
			   };

    //roundRectanglePath(context,x-THUMB_BORDER_WIDTH*2,y-THUMB_BORDER_WIDTH*2,THUMB_WIDTH+THUMB_BORDER_WIDTH*4, THUMB_HEIGHT+THUMB_BORDER_WIDTH*4,RADIUS);
    roundRectanglePath(context,x-THUMB_BORDER_WIDTH,y-THUMB_BORDER_WIDTH,THUMB_WIDTH+THUMB_BORDER_WIDTH*2, THUMB_HEIGHT+THUMB_BORDER_WIDTH*2,RADIUS);
    context.strokeStyle = THUMB_OUT_BORDER;
    context.lineWidth = THUMB_BORDER_WIDTH;
    context.stroke();

    // log("name: "+name+"; x: "+x+"; y: "+ y+"; width: "+ THUMB_WIDTH+"; height: " +THUMB_HEIGHT);
    name = name.substring(0, NAME_LENGTH);
    img.src = url;
    context.strokeStyle = "#2a2a2a";    
    context.font = NAME_STYLE; 
    context.lineWidth = '1';
    context.textBaseline = BASE_LINE;
    context.strokeText(name, x,y+THUMB_HEIGHT+NAME_MARGIN_TOP);
}

// left x, left y
function getOverlap(x1, y1)
{
    var e = new Object();
    e.pageX = x1 + canvas_margin_left;
    e.pageY = y1 + canvas_margin_top;
    return getRightestItem(elements, e);
}

drawed_nodes_num_in_level = new Array(0,0,0,0);
// 
function drawMemberTree(cxt, x1, y, x2, tree, level)
{
    // if mate exists
    if (tree.mates && tree.mates.length > 0)
    {
	if (level > 1)
	    var len = (tree.mates && tree.mates.length >= MAX_MATES) ?  MAX_MATES : 
	    ((tree.mates && tree.mates.length < MAX_MATES) ? tree.mates.length : 0);
	else
	    var len = tree.mates.length;
	//var len = child_num_in_level[level-1];//tree.children.length;

	var x_pad = x1 + (x2- x1- THUMB_WIDTH * (len+1) - THUMB_MARGIN_X * (len))/2;
	x_pad = x_pad > 0 ? x_pad : 0;

	if (obj = getOverlap(x_pad, y))
	{
	    x_pad = obj.x2 + THUMB_MARGIN_X;
	}
	// log("x_pad: "+x_pad);
	drawMember(cxt, tree.figureurl ? tree.figureurl : tree.gender == 'male' ? MALE_FIGURE : FEMALE_FIGURE, tree.name, 
		   x_pad, y);
	drawed_nodes_num_in_level[level]++;
	elements.push({id:tree.id, name:tree.name, gender:tree.gender, 
		       x1: x_pad, y1: y, x2: x_pad+THUMB_WIDTH, y2:y+THUMB_HEIGHT});	    
	names.push({id:tree.id, name:tree.name, gender:tree.gender, 
		    x1: x_pad, y1: y+THUMB_HEIGHT+NAME_MARGIN_TOP, x2: x_pad+THUMB_WIDTH, y2:y+THUMB_HEIGHT+NAME_MARGIN_TOP+NAME_HEIGHT});

	$.each(tree.mates, function(i, mate){
	    if(level > 1 && i >= MAX_MATES)
		return;
	    var xi = x_pad + (i+1)*(THUMB_WIDTH + THUMB_MARGIN_X);

	    if (obj = getOverlap(xi, y))
	    {
		xi = obj.x2 + THUMB_MARGIN_X;
	    }
	    drawMember(cxt, mate.figureurl ? mate.figureurl : mate.gender == 'male' ? MALE_FIGURE : FEMALE_FIGURE, mate.name, 
		       xi, y);
	    drawed_nodes_num_in_level[level]++;
	    elements.push({id:mate.id, name:mate.name, gender:mate.gender, 
			   x1: xi, y1: y, x2: xi+THUMB_WIDTH, y2:y+THUMB_HEIGHT});	    
	    names.push({id:mate.id, name:mate.name, gender:mate.gender, 
			x1: xi, y1: y+THUMB_HEIGHT+NAME_MARGIN_TOP, x2: xi+THUMB_WIDTH, y2:y+THUMB_HEIGHT+NAME_MARGIN_TOP+NAME_HEIGHT});

	});

	// draw a box to include the user and his mates
	// cxt.strokeRect(x_pad, y, (THUMB_WIDTH+THUMB_MARGIN_X)*(1+len), THUMB_HEIGHT+NAME_HEIGHT+NAME_MARGIN_TOP);
	// roundRectanglePath(cxt, x_pad, y, (THUMB_WIDTH+THUMB_MARGIN_X)*(1+len), THUMB_HEIGHT+NAME_HEIGHT+NAME_MARGIN_TOP, RADIUS);
	// cxt.strokeStyle = "red";
	// cxt.stroke();
    }
    else
    {
	var xm = x1 + (x2 - x1 - THUMB_WIDTH) / 2;
	if (obj = getOverlap(xm, y))
	{
	    xm = obj.x2 + THUMB_MARGIN_X;
	}
	drawMember(cxt, tree.figureurl ? tree.figureurl : tree.gender == 'male' ? MALE_FIGURE : FEMALE_FIGURE, tree.name, xm, y);
	drawed_nodes_num_in_level[level]++;
	// log("xm: "+xm);
	elements.push({id:tree.id, name:tree.name, 
		       gender:tree.gender,
		       x1: xm, y1: y, 
		       x2: xm+THUMB_WIDTH, y2:y+THUMB_HEIGHT});
	names.push({id:tree.id, name:tree.name, gender:tree.gender, 
		    x1: xm, y1: y+THUMB_HEIGHT+NAME_MARGIN_TOP, x2: xm+THUMB_WIDTH, y2:y+THUMB_HEIGHT+NAME_MARGIN_TOP+NAME_HEIGHT});

    }
    var root_x = (x1 + x2) / 2;
    var root_y = y + MEMBER_BLOCK_HEIGHT;

    // draw the children
    if (tree.children && tree.children.length>0)
    {
	circle(cxt, root_x, root_y, PARENT_RADIUS, LINE_STYLE);
	var len = child_num_in_level[level+1];//tree.children.length;
	// var more_btn = false;
	var index = 0;
	$.each(tree.children, function(i, subtree){
	    // if (more_btn)
	    // 	return;
	    // log(subtree.name);
	    var mates_num = (subtree.mates && subtree.mates.length >= MAX_MATES) ?  MAX_MATES : 
		((subtree.mates && subtree.mates.length < MAX_MATES) ? subtree.mates.length : 0);
	    
	    var child_width = ((x2-x1) / len) > (THUMB_WIDTH+THUMB_MARGIN_X) ? ((x2-x1) / len) : (THUMB_WIDTH+THUMB_MARGIN_X);
	    var child_x1 = x1 + index * child_width;
	    var head_y = y + MEMBER_BLOCK_HEIGHT + RELATIVE_LINE_HEIGHT;

	    // 后面有足够的空间画本行剩余的节点马？
	    var width_will_end_at = child_x1 + (len - drawed_nodes_num_in_level[level+1]) * (THUMB_WIDTH+THUMB_MARGIN_X);
	    if ( width_will_end_at > QIN_TREE_WIDTH)
	    {
	    	// child_x1 -= 1;
	    	// width_will_end_at = child_x1 + (len - drawed_nodes_num_in_level[level+1]) * (THUMB_WIDTH+THUMB_MARGIN_X);
		child_x1 = QIN_TREE_WIDTH - (len - drawed_nodes_num_in_level[level+1]) * (THUMB_WIDTH+THUMB_MARGIN_X);
	    }
	    if (child_x1 < 0)
		child_x1 = 0;

	    // 如果跟已有人物重合，则向后平移
	    // var obj = new Object();
	    if (obj = getOverlap(child_x1, head_y))
	    {
		// log('===================');
		child_x1 = obj.x2 + THUMB_MARGIN_X;
		// child_x2 = child_x1 + child_width;
		// head_x = (child_x1 + child_x2) / 2;
	    }

	    index += 1 + mates_num;
	    var child_x2 = child_x1 + (1 + mates_num) * child_width;
	    var head_x = (child_x1 + child_x2) / 2; // to the child, not the daughter in law

	    // 如果超出画布，则退出。
	    if (child_x1 > QIN_TREE_WIDTH)
		return;

	    // draw the subtree of this child
	    drawMemberTree(cxt, child_x1, head_y, child_x2, subtree, level+1);

	    // draw a line from root to this child
	    cxt.lineWidth = line_width[level];
	    cxt.strokeStyle = LINE_STYLE;
	    cxt.moveTo(root_x, root_y);
	    cxt.lineTo(head_x, head_y-CHILD_POINT_PADDING);
	    cxt.stroke();

	    circle(cxt, head_x, head_y-CHILD_POINT_PADDING, CHILD_RADIUS, LINE_STYLE);
	});
    }
}

function init_canvas(tree)
{
    // adaptable width automatically
    get_children_num_in_level(tree, 1, true);
    for (var i in child_num_in_level)
    {
	// if (VIEW_FROM_QQ_APP)
	//     child_num_in_level[i] = child_num_in_level[i] > MAX_HORIZON_CHILD_NUM ? MAX_HORIZON_CHILD_NUM : child_num_in_level[i];
	horizon_child_num = child_num_in_level[i] > horizon_child_num ? child_num_in_level[i] : horizon_child_num;
    }

    // if (horizon_child_num > 20)
    // {
    // 	THUMB_WIDTH = 40;
    // 	THUMB_HEIGHT = 40;
    // 	NAME_STYLE = "normal lighter 10px serif";
    // }
    if (VIEW_FROM_QQ_APP)
    {
	$("#main").width(BODY_WIDTH_FROM_QQ);
	$("#out-of-family-tree").width(BODY_WIDTH_FROM_QQ-60);
	// $("#family-tree").width(BODY_WIDTH_FROM_QQ);
    }
    var main_width = $("#main").width();
	// log("main width: "+main_width);
	
    var canvas_width = (THUMB_WIDTH+THUMB_MARGIN_X) * horizon_child_num + 20;
    QIN_TREE_WIDTH = canvas_width < QIN_TREE_MIN_WIDTH ? QIN_TREE_MIN_WIDTH : 
	    (canvas_width > QIN_TREE_WIDTH ? canvas_width : QIN_TREE_WIDTH);
    // QIN_TREE_WIDTH = QIN_TREE_WIDTH > (main_width-60) ? (main_width-60) : QIN_TREE_WIDTH;

    // set width and height to canvas and aside div
    canvas.width = QIN_TREE_WIDTH;
    canvas.height = QIN_TREE_HEIGHT;
    canvas.clientWidth = QIN_TREE_WIDTH;
    canvas.clientHeight = QIN_TREE_HEIGHT;
    canvas_top.width = QIN_TREE_WIDTH;
    canvas_top.height = QIN_TREE_HEIGHT;
    canvas_top.clientWidth = QIN_TREE_WIDTH;
    canvas_top.clientHeight = QIN_TREE_HEIGHT;

    var aside_width = main_width - QIN_TREE_WIDTH - 90;
    aside_width = aside_width < ASIDE_MIN_WIDTH ? ASIDE_MAX_WIDTH : aside_width;
    aside_width = aside_width > ASIDE_MAX_WIDTH ? ASIDE_MAX_WIDTH : aside_width;

    if (!VIEW_FROM_QQ_APP)
    {
	// $("#family-tree").width(QIN_TREE_WIDTH+10);
	$("#out-of-family-tree").width(QIN_TREE_WIDTH+30);
	$("#aside").width(aside_width);
    }
    // $("#out-of-family-tree").height(QIN_TREE_HEIGHT+20);

    // if (canvas.width - $("#family-tree").width() > 10)
    // {
    // 	$("#family-tree").css("overflow-x", "scroll").css("overflow-y", "hidden");
    // }
    
    // print grid every 100px on the canvas-mid
    if (DEBUG)
    {
	$("<canvas></canvas>").attr("id", "canvas_mid")
	    .attr("width", QIN_TREE_WIDTH)
	    .attr("height", QIN_TREE_HEIGHT)
	    .appendTo("#family-tree");

	canvas_mid = $("#canvas_mid")[0];
	canvas_mid.width = QIN_TREE_WIDTH;
	canvas_mid.height = QIN_TREE_HEIGHT;
	canvas_mid.clientWidth = QIN_TREE_WIDTH;
	canvas_mid.clientHeight = QIN_TREE_HEIGHT;

	var contex = $("#canvas_mid")[0].getContext("2d");
	for(var i=0; i<QIN_TREE_WIDTH;i+=10)
	{
	    for(var j=0; j<QIN_TREE_HEIGHT; j+=10)
	    {
		circle(contex, i, j, 1, "green");
	    }
	}
    }

}

var canv = $("<canvas></canvas>").attr("id", "canvas")
    .attr("width", QIN_TREE_WIDTH)
    .attr("height", QIN_TREE_HEIGHT)
    .appendTo("#family-tree");
var top = $("<canvas></canvas>").attr("id", "canvas_top")
    .attr("width", QIN_TREE_WIDTH)
    .attr("height", QIN_TREE_HEIGHT)
    .appendTo("#family-tree");

canvas = document.getElementById("canvas");
canvas_top = document.getElementById("canvas_top");
cxt = canvas.getContext("2d");
cxt_top = canvas_top.getContext("2d");
canvas_margin_left = pageX(canvas);//.offsetLeft;// + canvas.clientLeft;
canvas_margin_top = pageY(canvas);//.offsetTop;// + canvas.clientTop;

var uid = $("#userid").val();
if (window.sessionStorage && window.sessionStorage.getItem("user_"+uid))
{
    var tree = JSON.parse(window.sessionStorage.getItem("user_"+uid));
    init_canvas(tree[0]);
    drawMemberTree(cxt, 0, 5, QIN_TREE_WIDTH, tree[0], 1);
}
else
    $.getJSON("/tree/get_family_tree?userid="+uid,
	      function(tree){
		  // update the local storage
		  if (window.sessionStorage)
		      window.sessionStorage.setItem("user_"+uid, JSON.stringify(tree));
		  
		  init_canvas(tree[0]);
		  
		  // draw the family tree
		  drawMemberTree(cxt, 0, 5, QIN_TREE_WIDTH, tree[0], 1);
	      });

